package com.wk.code.wkserver.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wk.code.wkserver.constant.Constant;
import com.wk.code.wkserver.constant.EmailConstant;
import com.wk.code.wkserver.constant.NumberConstant;
import com.wk.code.wkserver.constant.enums.TechApplyRecordStatusEnum;
import com.wk.code.wkserver.constant.enums.UserStatusEnum;
import com.wk.code.wkserver.constant.enums.UserTypeEnum;
import com.wk.code.wkserver.entity.SysUser;
import com.wk.code.wkserver.entity.User;
import com.wk.code.wkserver.entity.UserInfo;
import com.wk.code.wkserver.exception.BizException;
import com.wk.code.wkserver.manager.AsyncTaskManager;
import com.wk.code.wkserver.mapper.UserInfoMapper;
import com.wk.code.wkserver.request.admin.SysUserRequest;
import com.wk.code.wkserver.request.app.SetCustomerRequest;
import com.wk.code.wkserver.request.app.UserInfoRequest;
import com.wk.code.wkserver.request.app.WxUserInfoRequest;
import com.wk.code.wkserver.response.app.UserInfoDetailResponse;
import com.wk.code.wkserver.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wk.code.wkserver.utils.DateUtils;
import com.wk.code.wkserver.utils.PasswordUtils;
import com.wk.code.wkserver.utils.RegUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.Objects;

/**
 * <p>
 * 用户基本信息表 服务实现类
 * </p>
 *
 * @author wq
 * @since 2021-08-15
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements IUserInfoService {


    @Resource
    private IUserService userService;

    @Resource
    private ITechApplyRecordService techApplyRecordService;

    @Resource
    private ISysUserService sysUserService;

    @Resource
    private AsyncTaskManager asyncTaskManager;

    @Resource
    private IMailService mailService;


    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void createUserInfo(Integer userId, WxUserInfoRequest request) {
        UserInfo userInfo = new UserInfo();
        userInfo.setUserId(userId);
        userInfo.setCity(request.getCity());
        userInfo.setProvince(request.getProvince());
        userInfo.setCountry(request.getCountry());
        save(userInfo);
    }

    @Override
    public void updateUserInfo(Integer userId, UserInfoRequest request) {
        User user = userService.selectById(userId);
        if (Objects.nonNull(user)) {
            if (user.getRegisterType().equals(UserTypeEnum.DEMAND_USER.getCode())) {
                //发单用户填写资料后可以直接发
                updateDemandUserInfo(userId, request);
                //修改用户为已认证(填写资料)
                user.setIsAuth(NumberConstant.TWO);
                userService.updateById(user);
            } else {
                //技术用户修改资料 查询是否可以修改资料
                UserInfo userInfo = baseMapper.selectOne(new LambdaQueryWrapper<UserInfo>().
                        eq(UserInfo::getUserId, userId));
                if (Objects.nonNull(userInfo)) {
                    String updateMonth = DateUtils.localDateTime2DateStr(DateUtils.YYYY_MM, userInfo.getUpdateTime());
                    LocalDateTime nowDate = DateUtils.date2LocalDateTime(new Date());
                    String nowMonth = DateUtils.localDateTime2DateStr(DateUtils.YYYY_MM, nowDate);
                    System.out.println("updateMonth:" + updateMonth);
                    System.out.println("nowMonth:" + nowMonth);
                    if (updateMonth.equals(nowMonth)) {
                        throw new BizException("当前月只能修改一次资料哦");
                    }
                }
                userInfo.setEmail(request.getEmail());
                userInfo.setQqAccount(request.getQqAccount());
                userInfo.setWechatAccount(request.getWechatAccount());
                userInfo.setRealName(request.getRealName());
                userInfo.setTechTypeId(request.getTechTypeId());
                userInfo.setAlipayAccount(request.getAlipayAccount());
                updateById(userInfo);
            }
        }
    }

    @Override
    public void applyTechUser(Integer userId, UserInfoRequest request) {
        User user = userService.selectById(userId);
        if (Objects.nonNull(user)) {
            if (user.getRegisterType().equals(UserTypeEnum.DEMAND_USER.getCode())) {
                //默认是需求用户 申请成为技术
                updateTechUserInfo(user, userId, request);
            }
        }
    }

    @Override
    public UserInfoDetailResponse detail(Integer userId) {
        UserInfoDetailResponse response = new UserInfoDetailResponse();
        User user = userService.selectById(userId);
        if (Objects.nonNull(user)) {
            if (user.getStatus().equals(UserStatusEnum.PROHIBIT.getCode())) {
                throw new BizException("账号已被封禁,请联系客服");
            }
        }
        UserInfo userInfo = baseMapper.selectOne(new LambdaQueryWrapper<UserInfo>().
                eq(UserInfo::getUserId, userId));
        if (Objects.nonNull(userInfo)) {
            if (StringUtils.isNotEmpty(user.getMobile())) {
                response.setMobile(user.getMobile());
            }
            if (StringUtils.isNotEmpty(userInfo.getQqAccount())) {
                response.setQqAccount(userInfo.getQqAccount());
            }
            if (StringUtils.isNotEmpty(userInfo.getEmail())) {
                response.setEmail(userInfo.getEmail());
            }
            if (StringUtils.isNotEmpty(userInfo.getWechatAccount())) {
                response.setWechatAccount(userInfo.getWechatAccount());
            }
            if (StringUtils.isNotEmpty(userInfo.getAlipayAccount())) {
                response.setAlipayAccount(userInfo.getAlipayAccount());
            }
            if (StringUtils.isNotEmpty(userInfo.getRealName())) {
                response.setRealName(userInfo.getRealName());
            }
            if (Objects.nonNull(userInfo.getTechTypeId())) {
                response.setTechTypeId(userInfo.getTechTypeId());
            }
            return response;
        }
        return null;
    }

    @Override
    public void setCustomer(SetCustomerRequest request) {
        //修改该用户的注册类型
        User user = userService.selectById(request.getUserId());
        if (Objects.isNull(user)) {
            throw new BizException("该用户信息不存在");
        }
        if (!user.getRegisterType().equals(UserTypeEnum.CUSTOMER.getCode())) {
            user.setRegisterType(UserTypeEnum.CUSTOMER.getCode());
        }
        userService.updateById(user);
        //设置用户信息
        UserInfo userInfo = baseMapper.selectOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getUserId, request.getUserId()));
        userInfo.setAlipayAccount(request.getAlipayAccount());
        userInfo.setEmail(request.getEmail());
        userInfo.setQqAccount(request.getQqAccount());
        userInfo.setRealName(request.getRealName());
        userInfo.setWechatAccount(request.getWechatAccount());
        baseMapper.updateById(userInfo);
        //新增后台系统用户设置角色为客服
        createSysUser(user, request);
        //发送邮件通知
        asyncTaskManager.execute(() -> sendCustomerEmail(user));
    }

    @Override
    public void prohibitUser(Integer userId) {
        userService.updateUserStatus(userId);
    }

    /**
     * 设置系统用户
     *
     * @param user    用户
     * @param request 请求参数
     */
    private void createSysUser(User user, SetCustomerRequest request) {
        SysUserRequest sysUserRequest = new SysUserRequest();
        //密码默认是邮箱地址
        sysUserRequest.setPassword(request.getEmail());
        sysUserRequest.setEmail(request.getEmail());
        sysUserRequest.setMobile(request.getMobile());
        sysUserRequest.setNickname(user.getNickname());
        sysUserRequest.setUserId(user.getId());
        //设置客服的角色ID
        sysUserRequest.setRoleId(10000);
        sysUserService.addUser(sysUserRequest);
    }

    /**
     * 客服设置成功邮件通知
     *
     * @param user user
     */
    private void sendCustomerEmail(User user) {
        SysUser sysUser = sysUserService.selectAdminUser();
        if (Objects.nonNull(sysUser)) {
            mailService.sendMail(sysUser.getEmail(), String.format(EmailConstant.SET_CUSTOMER, user.getNickname()));
        }
    }


    /**
     * 更新技术用户信息
     *
     * @param userId  用户ID
     * @param request 请求参数
     */
    private void updateTechUserInfo(User user, Integer userId, UserInfoRequest request) {
        checkUserInfo(request);
        if (Objects.isNull(request.getTechTypeId())) {
            throw new BizException("请选择技术类型");
        }
        if (StringUtils.isEmpty(request.getRealName())) {
            throw new BizException("请输入真实名称");
        }
        if (StringUtils.isEmpty(request.getAlipayAccount())) {
            throw new BizException("请输入支付宝账号");
        }
        UserInfo userInfo = baseMapper.selectOne(new LambdaQueryWrapper<UserInfo>().
                eq(UserInfo::getUserId, userId));
        userInfo.setEmail(request.getEmail());
        userInfo.setQqAccount(request.getQqAccount());
        userInfo.setWechatAccount(request.getWechatAccount());
        userInfo.setRealName(request.getRealName());
        userInfo.setTechTypeId(request.getTechTypeId());
        userInfo.setAlipayAccount(request.getAlipayAccount());
        updateById(userInfo);
        //保存申请记录 为待审核
        createTechApplyRecord(userId, TechApplyRecordStatusEnum.VO_VERIFY.getCode());
        //发送邮件给超级管理员
        asyncTaskManager.execute(() -> sendEmail(user));
    }

    /**
     * 发送邮件给超级管理员
     *
     * @param user 用户
     */
    private void sendEmail(User user) {
        SysUser sysUser = sysUserService.selectAdminUser();
        if (Objects.nonNull(sysUser)) {
            mailService.sendMail(sysUser.getEmail(), String.format(EmailConstant.TECH_USER_APPLY, user.getNickname()));
        }

    }

    /**
     * 审核状态
     *
     * @param userId       用户ID
     * @param verifyStatus 审核状态
     */
    private void createTechApplyRecord(Integer userId, Integer verifyStatus) {
        techApplyRecordService.save(userId, null, verifyStatus, null);
    }

    /**
     * 更新发单用户信息
     *
     * @param userId  用户ID
     * @param request 请求参数
     */
    private void updateDemandUserInfo(Integer userId, UserInfoRequest request) {
        checkUserInfo(request);
        UserInfo userInfo = baseMapper.selectOne(new LambdaQueryWrapper<UserInfo>().
                eq(UserInfo::getUserId, userId));
        userInfo.setEmail(request.getEmail());
        if (StringUtils.isNotEmpty(request.getQqAccount())) {
            userInfo.setQqAccount(request.getQqAccount());
        }
        userInfo.setWechatAccount(request.getWechatAccount());
        updateById(userInfo);

    }

    private void checkUserInfo(UserInfoRequest request) {
        if (StringUtils.isEmpty(request.getEmail())) {
            throw new BizException("请输入邮箱");
        }
        if (!RegUtils.isEmail(request.getEmail())) {
            throw new BizException("请输入正确邮箱");
        }
        if (StringUtils.isEmpty(request.getWechatAccount())) {
            throw new BizException("请输入微信号");
        }
    }
}
